package com.bridgeintelligent.tag.customer.service;

import com.bridgeintelligent.tag.constants.bulkload.IssueMqMsg;
import com.bridgeintelligent.tag.constants.bulkload.MQConfig;
import com.bridgeintelligent.tag.customer.entity.CustomersPage;
import com.bridgeintelligent.tag.customer.entity.IssueLog;
import com.bridgeintelligent.tag.customer.entity.IssueTask;
import com.bridgeintelligent.tag.customer.entity.IssueTaskLog;
import com.bridgeintelligent.tag.customer.mapper.CustomersMapper;
import com.bridgeintelligent.tag.customer.mapper.IssueLogMapper;
import com.bridgeintelligent.tag.customer.mapper.IssueTaskMapper;
import com.bridgeintelligent.tag.customer.model.IssueTaskModel;
import com.bridgeintelligent.tag.customer.model.IssueTaskQueryModel;
import com.bridgeintelligent.tag.customer.vo.IssueTaskVO;
import com.bridgeintelligent.tag.utils.DateHelper;
import com.bridgeintelligent.tag.utils.IdWorker;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @description
 * @author: grp 2021-02-23 14:48
 **/
@Service
@Slf4j
@AllArgsConstructor
public class IssueTaskServiceImpl implements IIssueTaskService{

    private final IssueTaskMapper issueTaskMapper;
    private CustomersMapper customersMapper;
    private IIssueSendService issueSendService;

    private final IssueLogMapper issueLogMapper;
    protected RocketMQTemplate rocketMQTemplate;
    private ObjectMapper objectMapper;

    @Override
    public int countById(String id) {
        return issueTaskMapper.countById(id);
    }

    @Override
    public int countByName(String name) {
        return issueTaskMapper.countByName(name);
    }

    @Override
    public int countByNameAndNotId(String id, String name) {
        return issueTaskMapper.countByNameAndNotId(name,id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void put(IssueTaskModel model) {
        IssueTask issue = new IssueTask();
        BeanUtils.copyProperties(model, issue);
        issue.setUpdateTime(new Date());
        issueTaskMapper.update(issue);
    }

    @Override
    public CustomersPage<IssueTaskVO> list(IssueTaskQueryModel model) {
        if (StringUtils.isNotEmpty(model.getStart())) {
            model.setStart(model.getStart() + " 00:00:00");
        }
        if (StringUtils.isNotEmpty(model.getEnd())) {
            model.setEnd(model.getEnd() + " 23:59:59");
        }
        Page page = PageHelper.startPage(model.getPageNumber(), model.getPageSize());
        List<IssueTaskVO> list = issueTaskMapper.findList(model);
        return new CustomersPage<IssueTaskVO>().setContent(list).setTotalPages(page.getPages()).setRequestPager(model.getPageNumber())
                .setSize(model.getPageSize()).setTotalElements(page.getTotal());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void del(String id) {
        IssueTask issue = new IssueTask();
        issue.setId(id);
        issue.setUpdateTime(new Date());
        issue.setIsDel("01");
        issueTaskMapper.update(issue);
    }

    @Override
    public IssueTaskVO getDetail(String id) {
        IssueTaskVO issueVO = issueTaskMapper.findOne(id);
        if (issueVO != null && !StringUtils.isEmpty(issueVO.getFields())) {
            //处理部分字段，方便前端回显
            Map<String, String> valueMap = new HashMap<>();
            String[] values = issueVO.getFields()
                    .split(",");
            for (String dimId : values) {
                valueMap.put(dimId, customersMapper.findNameByDimId(dimId));
            }
            issueVO.setMap(valueMap);
        }
        return issueVO;

    }

    @Override
    public void changState(IssueTaskModel model) {
        issueTaskMapper.update(new IssueTask().setState(model.getState()).setId(model.getId()).setUpdateTime(new Date()).setWeeks(model.getWeeks()));
    }

    @Override
    public void workByHand() {
        log.info("---------手工下发失效定时开始-----------");
        try{
            int num = issueTaskMapper.updateToStop(DateHelper.currentDateTime("yyyy-MM-dd"),new Date());
            log.info("手工发现失效的任务配置：{}个", num);
            int tasks = issueTaskMapper.updateToStopTask(DateHelper.currentDateTime("yyyy-MM-dd"),new Date());
            log.info("手工发现失效的任务：{}个", tasks);
            int customersStop = issueTaskMapper.updateCustomersToStop(new Date());
            log.info("手工发现客群失效导致失效的任务配置：{}个", customersStop);
            int customersTaskStop = issueTaskMapper.updateCustomersToStopTask(new Date());
            log.info("手工发现客群失效导致失效的任务：{}个", customersTaskStop);
        } catch (Exception e){
            log.error("手工发现任务失效",e);
        }
        log.info("---------手工下发定时开始-----------");
        List<IssueTask> tasks = issueTaskMapper.findValidTasks(DateHelper.currentDateTime("yyyy-MM-dd"));
        if (CollectionUtils.isNotEmpty(tasks)) {
            for (IssueTask task : tasks) {
                try{
                    issueSendService.sendByTaskId(task.getId());
                } catch (Exception e){
                    log.error("手工定时",e);
                }
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void immediateTask(IssueTask task) {
        String indexById = customersMapper.findIndexById(task.getCustomersId());
        //计算时间
        String dataDate = issueTaskMapper.indexLastTime(indexById);
        //对于立即下发，只校验0待运行、1正在运行的状态(2成功3失败的状态不管)
        Integer count = issueTaskMapper.immediateCheckCount(task.getId());
        if(count>0){
            log.info(dataDate+"：立即下发任务："+task.getId()+"存在0/1状态");
            return;
        }
        //执行首次插入动作
        IssueTaskLog taskLog = new IssueTaskLog();
        BeanUtils.copyProperties(task, taskLog);
        taskLog.setIssueId(task.getId());
        taskLog.setId(IdWorker.nextId());
        taskLog.setIsDel("00");
        issueLogMapper.addTaskLog(taskLog);
        IssueLog issueLog = new IssueLog();
        issueLogMapper.addLog(issueLog.setId(taskLog.getId())
                .setUpdateTime(new Date()).setCreateTime(new Date()).setDataDate(dataDate)
                .setState("0").setIsRetry("1"));
        try {
            IssueMqMsg issueMqMsg = new IssueMqMsg();
            issueMqMsg.setId(issueLog.getId());
            String msg = objectMapper.writeValueAsString(issueMqMsg);
            rocketMQTemplate.convertAndSend(MQConfig.FILE_ISSUE_TOPIC, msg);
            issueLogMapper.updateLog(new IssueLog().setId(issueLog.getId())
                    .setState("1").setUpdateTime(new Date()));
            log.info("客群立即下发发送mq成功：{}",issueLog.getId());
        } catch (Exception e) {
            issueLogMapper.updateLog(new IssueLog().setId(issueLog.getId())
                    .setState("3").setUpdateTime(new Date()).setReason("发送MQ消息失败"));
            log.error("客群立即下发任务失败:"+issueLog.getId(), e);
        }
    }

}
